#region Using Directives

using JetBrains.Application.Progress;
using JetBrains.ReSharper.Daemon;
using JetBrains.ReSharper.Psi;

#endregion

namespace CCN.StyleCopPlugin
{
    /// <summary>
    /// Process to check files using <c>StyleCop</c>
    /// </summary>
    public class StyleCopDaemonStageProcess : IDaemonStageProcess
    {
        private readonly IDaemonProcess _myDaemonProcess;

        /// <summary>
        /// Initializes a new instance of the <see cref="StyleCopDaemonStageProcess"/> class.
        /// </summary>
        /// <param name="daemonProcess">The daemon process.</param>
        public StyleCopDaemonStageProcess(IDaemonProcess daemonProcess)
        {
            _myDaemonProcess = daemonProcess;
        }

        #region IDaemonStageProcess Members

        /// <summary>
        /// Executes the process and returns resulting highlightings and embedded objects to be inserted into the editor.
        /// The process should check for <see cref="P:JetBrains.ReSharper.Daemon.IDaemonProcess.InterruptFlag"/> periodically (with intervals less than 100 ms)
        /// and throw <see cref="T:JetBrains.Application.Progress.ProcessCancelledException"/> if it is true.
        /// Failing to do so may cause the program to prevent user from typing while analysing the code.
        /// </summary>
        /// <returns>
        /// New highlightings and embedded objects. Return <c>null</c> if this stage doesn't produce
        /// any of them.
        /// </returns>
        /// <exception cref="ProcessCancelledException"><c>ProcessCancelledException</c>.</exception>
        public DaemonStageProcessResult Execute()
        {
            // Creating container to put highlightings to
            var result = new DaemonStageProcessResult();

            // Getting PSI (AST) for the file being highlighted
            var manager = PsiManager.GetInstance(_myDaemonProcess.Solution);
            var file = manager.GetPsiFile(_myDaemonProcess.ProjectFile);

            if(file == null || file.Language.Name != "CSHARP")
            {
                return result;
            }

            // Running visitor against the PSI
            var fileProcessor = new StyleCopFileProcessor(_myDaemonProcess);
            fileProcessor.ProcessFile(file);

            // Checking if the daemon is interrupted by user activity
            if(_myDaemonProcess.InterruptFlag)
            {
                throw new ProcessCancelledException();
            }

            // Fill in the result
            result.FullyRehighlighted = true;
            result.Highlightings = fileProcessor.Highlightings.ToArray();

            return result;
        }

        #endregion
    }
}